import os
import sys
from colorama import init, Fore, Style
from typing import List, Dict, Any, Optional

from kimi_client import KimiClient
from utils.file_ops import FileOperations
from utils.system_info import SystemInfo
from config import ConfigManager

class TerminalUI:
    """终端用户界面类"""
    
    def __init__(self):
        """初始化终端界面"""
        init(autoreset=True)  # 初始化colorama
        self.config_manager = ConfigManager()
        self.config = self.config_manager.load_config()
        self.kimi_client = None
        self.commands = {
            "help": self.show_help,
            "clear": self.clear_history,
            "exit": self.exit_program,
            "config": self.show_config,
            "file": self.handle_file_command,
            "system": self.handle_system_command,
            "history": self.show_history,
            "reset": self.reset_conversation
        }
        
        # Windows系统不支持readline，移除自动补全功能
        # 在Linux/macOS上可以添加readline支持
    
    def command_completer(self, text: str, state: int) -> Optional[str]:
        """命令自动补全函数（Windows不支持）"""
        return None
    
    def initialize_kimi_client(self) -> bool:
        """初始化Kimi客户端"""
        try:
            api_key = self.config_manager.get("api_key")
            if not api_key:
                print(Fore.YELLOW + "警告: 未设置API密钥，请先运行配置设置")
                if self.config_manager.setup_initial_config():
                    self.config = self.config_manager.load_config()
                    api_key = self.config_manager.get("api_key")
            
            if api_key:
                self.kimi_client = KimiClient(api_key=api_key)
                self.kimi_client.add_system_message()
                return True
            else:
                print(Fore.RED + "错误: 无法初始化Kimi客户端，缺少API密钥")
                return False
                
        except Exception as e:
            print(Fore.RED + f"初始化Kimi客户端失败: {e}")
            return False
    
    def show_help(self) -> None:
        """显示帮助信息"""
        help_text = f"""
{Fore.CYAN}=== Kimi终端助手 - 命令帮助 ==={Style.RESET_ALL}

{Fore.GREEN}基础命令:{Style.RESET_ALL}
  {Fore.YELLOW}/help{Style.RESET_ALL}      - 显示此帮助信息
  {Fore.YELLOW}/clear{Style.RESET_ALL}     - 清空对话历史
  {Fore.YELLOW}/history{Style.RESET_ALL}   - 显示对话历史
  {Fore.YELLOW}/reset{Style.RESET_ALL}     - 重置对话（保留系统消息）
  {Fore.YELLOW}/config{Style.RESET_ALL}    - 显示当前配置
  {Fore.YELLOW}/exit{Style.RESET_ALL}      - 退出程序

{Fore.GREEN}文件操作:{Style.RESET_ALL}
  {Fore.YELLOW}/file read <文件名>{Style.RESET_ALL}    - 读取并分析文件
  {Fore.YELLOW}/file list [目录]{Style.RESET_ALL}      - 列出目录内容
  {Fore.YELLOW}/file info <文件名>{Style.RESET_ALL}    - 获取文件信息

{Fore.GREEN}系统信息:{Style.RESET_ALL}
  {Fore.YELLOW}/system info{Style.RESET_ALL}          - 显示系统信息
  {Fore.YELLOW}/system processes{Style.RESET_ALL}     - 显示进程信息
  {Fore.YELLOW}/system disks{Style.RESET_ALL}         - 显示磁盘信息

{Fore.CYAN}普通对话:{Style.RESET_ALL}
  直接输入消息即可与Kimi进行对话
  支持多行输入（按Ctrl+D或输入空行结束）

{Fore.MAGENTA}提示:{Style.RESET_ALL}
  - 使用Tab键自动补全命令
  - 支持命令简写（如 /h 代替 /help）
  - 所有文件路径支持相对路径和绝对路径
"""
        print(help_text)
    
    def clear_history(self) -> None:
        """清空对话历史"""
        if self.kimi_client:
            self.kimi_client.clear_history()
            print(Fore.GREEN + "对话历史已清空")
        else:
            print(Fore.RED + "Kimi客户端未初始化")
    
    def show_history(self) -> None:
        """显示对话历史"""
        if self.kimi_client:
            history = self.kimi_client.get_history()
            if not history:
                print(Fore.YELLOW + "对话历史为空")
                return
            
            print(Fore.CYAN + "=== 对话历史 ===")
            for i, msg in enumerate(history, 1):
                role = msg["role"]
                content = msg["content"][:100] + "..." if len(msg["content"]) > 100 else msg["content"]
                
                if role == "user":
                    print(f"{Fore.GREEN}{i}. 用户: {content}{Style.RESET_ALL}")
                elif role == "assistant":
                    print(f"{Fore.BLUE}{i}. Kimi: {content}{Style.RESET_ALL}")
                else:
                    print(f"{Fore.YELLOW}{i}. 系统: {content}{Style.RESET_ALL}")
        else:
            print(Fore.RED + "Kimi客户端未初始化")
    
    def reset_conversation(self) -> None:
        """重置对话"""
        if self.kimi_client:
            system_message = None
            # 保留系统消息
            for msg in self.kimi_client.get_history():
                if msg["role"] == "system":
                    system_message = msg["content"]
                    break
            
            self.kimi_client.clear_history()
            if system_message:
                self.kimi_client.add_system_message(system_message)
            
            print(Fore.GREEN + "对话已重置")
        else:
            print(Fore.RED + "Kimi客户端未初始化")
    
    def show_config(self) -> None:
        """显示当前配置"""
        print(Fore.CYAN + "=== 当前配置 ===")
        for key, value in self.config.items():
            if key == "api_key" and value:
                masked_key = value[:4] + "*" * (len(value) - 8) + value[-4:] if len(value) > 8 else "***"
                print(f"{Fore.YELLOW}{key}: {masked_key}{Style.RESET_ALL}")
            else:
                print(f"{Fore.YELLOW}{key}: {value}{Style.RESET_ALL}")
    
    def handle_file_command(self, args: List[str]) -> None:
        """处理文件相关命令"""
        if not args:
            print(Fore.RED + "文件命令需要参数，使用 /file help 查看帮助")
            return
        
        subcommand = args[0].lower()
        
        if subcommand == "read" and len(args) >= 2:
            try:
                content = FileOperations.read_file(args[1])
                analysis = FileOperations.analyze_file_content(content)
                
                print(Fore.GREEN + f"文件读取成功: {args[1]}")
                print(Fore.CYAN + f"类型: {analysis['content_type']}")
                print(Fore.CYAN + f"行数: {analysis['total_lines']}")
                print(Fore.CYAN + f"字符数: {analysis['total_chars']}")
                
                if analysis['has_more']:
                    print(Fore.YELLOW + f"预览 (前50行):")
                else:
                    print(Fore.YELLOW + "内容:")
                
                print(Fore.WHITE + analysis['preview'])
                
            except Exception as e:
                print(Fore.RED + f"文件读取失败: {e}")
                
        elif subcommand == "list":
            directory = args[1] if len(args) >= 2 else "."
            try:
                items = FileOperations.list_directory(directory)
                print(Fore.GREEN + f"目录内容: {directory}")
                for item in items:
                    item_type = "📁" if item["is_dir"] else "📄"
                    size = SystemInfo.format_bytes(item["size"]) if not item["is_dir"] else ""
                    print(f"{item_type} {Fore.CYAN}{item['name']}{Style.RESET_ALL} {size}")
                    
            except Exception as e:
                print(Fore.RED + f"目录列表失败: {e}")
                
        elif subcommand == "info" and len(args) >= 2:
            try:
                info = FileOperations.get_file_info(args[1])
                print(Fore.GREEN + f"文件信息: {args[1]}")
                for key, value in info.items():
                    if key in ["created", "modified"]:
                        from datetime import datetime
                        value = datetime.fromtimestamp(value).strftime("%Y-%m-%d %H:%M:%S")
                    elif key == "size":
                        value = SystemInfo.format_bytes(value)
                    print(f"{Fore.YELLOW}{key}: {Fore.WHITE}{value}{Style.RESET_ALL}")
                    
            except Exception as e:
                print(Fore.RED + f"获取文件信息失败: {e}")
                
        else:
            print(Fore.RED + "未知的文件命令，使用 /file help 查看帮助")
    
    def handle_system_command(self, args: List[str]) -> None:
        """处理系统相关命令"""
        if not args:
            print(Fore.RED + "系统命令需要参数，使用 /system help 查看帮助")
            return
        
        subcommand = args[0].lower()
        
        if subcommand == "info":
            try:
                info = SystemInfo.get_system_info()
                print(Fore.GREEN + "=== 系统信息 ===")
                for key, value in info.items():
                    if isinstance(value, dict):
                        print(f"{Fore.YELLOW}{key}:")
                        for subkey, subvalue in value.items():
                            if subkey == "percent":
                                subvalue = f"{subvalue}%"
                            elif isinstance(subvalue, (int, float)) and subvalue > 1024:
                                subvalue = SystemInfo.format_bytes(subvalue)
                            print(f"  {Fore.CYAN}{subkey}: {Fore.WHITE}{subvalue}{Style.RESET_ALL}")
                    else:
                        print(f"{Fore.YELLOW}{key}: {Fore.WHITE}{value}{Style.RESET_ALL}")
                        
            except Exception as e:
                print(Fore.RED + f"获取系统信息失败: {e}")
                
        elif subcommand == "processes":
            try:
                processes = SystemInfo.get_process_info()
                print(Fore.GREEN + "=== 进程信息 (前10个) ===")
                print(f"{Fore.YELLOW}{'PID':<8} {'名称':<20} {'CPU%':<6} {'内存%':<6}")
                for proc in processes:
                    print(f"{Fore.CYAN}{proc.get('pid', 'N/A'):<8} {Fore.WHITE}{proc.get('name', 'N/A')[:18]:<20} {proc.get('cpu_percent', 0):<6.1f} {proc.get('memory_percent', 0):<6.1f}")
                    
            except Exception as e:
                print(Fore.RED + f"获取进程信息失败: {e}")
                
        elif subcommand == "disks":
            try:
                disks = SystemInfo.get_disk_info()
                print(Fore.GREEN + "=== 磁盘信息 ===")
                for disk in disks:
                    print(f"{Fore.YELLOW}设备: {disk['device']}")
                    print(f"{Fore.CYAN}挂载点: {disk['mountpoint']}")
                    print(f"{Fore.CYAN}类型: {disk['fstype']}")
                    print(f"{Fore.CYAN}总空间: {SystemInfo.format_bytes(disk['total'])}")
                    print(f"{Fore.CYAN}已用: {SystemInfo.format_bytes(disk['used'])} ({disk['percent']}%)")
                    print(f"{Fore.CYAN}可用: {SystemInfo.format_bytes(disk['free'])}")
                    print()
                    
            except Exception as e:
                print(Fore.RED + f"获取磁盘信息失败: {e}")
                
        else:
            print(Fore.RED + "未知的系统命令，使用 /system help 查看帮助")
    
    def exit_program(self) -> None:
        """退出程序"""
        print(Fore.GREEN + "感谢使用Kimi终端助手，再见！")
        sys.exit(0)
    
    def process_command(self, command: str) -> bool:
        """处理用户输入的命令"""
        command = command.strip()
        
        # 空命令
        if not command:
            return True
        
        # 处理以/开头的命令
        if command.startswith('/'):
            parts = command[1:].split()
            if not parts:
                return True
            
            cmd = parts[0].lower()
            args = parts[1:]
            
            # 命令简写支持
            cmd_aliases = {
                'h': 'help',
                'c': 'clear',
                'e': 'exit',
                'conf': 'config',
                'f': 'file',
                's': 'system',
                'hist': 'history',
                'r': 'reset'
            }
            
            cmd = cmd_aliases.get(cmd, cmd)
            
            if cmd in self.commands:
                try:
                    # 检查命令是否需要参数
                    if cmd in ["file", "system"]:
                        self.commands[cmd](args)
                    else:
                        # 不需要参数的命令
                        self.commands[cmd]()
                except Exception as e:
                    print(Fore.RED + f"命令执行错误: {e}")
            else:
                print(Fore.RED + f"未知命令: {cmd}，使用 /help 查看可用命令")
            
            return True
        
        # 普通对话
        if self.kimi_client:
            try:
                print(Fore.BLUE + "Kimi 正在思考..." + Style.RESET_ALL)
                response = self.kimi_client.chat(command, self.config.get("temperature", 0.6))
                print(Fore.BLUE + "Kimi: " + Fore.WHITE + response + Style.RESET_ALL)
            except Exception as e:
                print(Fore.RED + f"对话失败: {e}")
        else:
            print(Fore.RED + "Kimi客户端未初始化，请先设置API密钥")
        
        return True
    
    def run(self) -> None:
        """运行终端界面"""
        print(Fore.CYAN + "=== Kimi终端助手 ===")
        print(Fore.YELLOW + "输入 /help 查看可用命令")
        print(Fore.YELLOW + "输入 /exit 退出程序")
        print()
        
        # 初始化Kimi客户端
        if not self.initialize_kimi_client():
            print(Fore.YELLOW + "请先设置API密钥才能使用对话功能")
        
        # 主循环
        while True:
            try:
                prompt = Fore.GREEN + "你: " + Style.RESET_ALL
                user_input = input(prompt).strip()
                
                if not self.process_command(user_input):
                    break
                    
            except KeyboardInterrupt:
                print("\n" + Fore.YELLOW + "输入 /exit 退出程序")
            except EOFError:
                print("\n" + Fore.YELLOW + "输入 /exit 退出程序")
            except Exception as e:
                print(Fore.RED + f"发生错误: {e}")
